/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import fs from 'fs';
import * as path from 'path';
import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger';
    
const logger = Logger.getLogger(LOG_MODULE_TYPE.TOOL, 'Config');

/**
 * SDK配置接口
 */
export interface SDKConfig {
    name: string;
    path: string;
    moduleName: string;
}

/**
 * 配置接口定义
 */
export interface DepGraphConfig {
    projectPath: string;
    sdk: SDKConfig;
    cSdkPaths: string[];
    outputDir: string;
    sourceFiles: string[];
}

/**
 * 配置类，支持从配置文件读取配置项
 */
export class Config {
    private static instance: Config | null = null;
    private config: DepGraphConfig | null = null;
    private defaultConfig: DepGraphConfig = {
        projectPath: '',
        sdk: {
            name: 'ohos',
            path: '',
            moduleName: ''
        },
        cSdkPaths: [],
        outputDir: './out',
        sourceFiles: []
    };

    private constructor() {}

    /**
     * 获取配置类的单例实例
     */
    public static getInstance(): Config {
        if (!Config.instance) {
            Config.instance = new Config();
        }
        return Config.instance;
    }

    /**
     * 从配置文件加载配置
     * @param configPath 配置文件路径
     */
    public loadFromFile(configPath: string): boolean {
        try {
            if (!fs.existsSync(configPath)) {
                logger.error(`配置文件不存在: ${configPath}`);
                return false;
            }

            const content = fs.readFileSync(configPath, 'utf-8');
            const configObj = JSON.parse(content);
            
            this.config = {
                projectPath: configObj.projectPath || this.defaultConfig.projectPath,
                sdk: configObj.sdk || this.defaultConfig.sdk,
                cSdkPaths: configObj.cSdkPaths || this.defaultConfig.cSdkPaths,
                outputDir: configObj.outputDir || this.defaultConfig.outputDir,
                sourceFiles: configObj.sourceFiles || this.defaultConfig.sourceFiles
            };
            
            logger.info(`成功从配置文件加载配置: ${configPath}`);
            return true;
        } catch (error) {
            logger.error(`加载配置文件失败: ${error}`);
            return false;
        }
    }

    /**
     * 设置项目路径
     * @param projectPath 项目路径
     */
    public setProjectPath(projectPath: string): void {
        if (!this.config) {
            this.config = { ...this.defaultConfig };
        }
        this.config.projectPath = projectPath;
    }

    /**
     * 设置SDK配置
     * @param sdk SDK配置对象
     */
    public setSdk(sdk: SDKConfig): void {
        if (!this.config) {
            this.config = { ...this.defaultConfig };
        }
        this.config.sdk = sdk;
    }

    /**
     * 设置C/C++ SDK路径列表
     * @param cSdkPaths C/C++ SDK路径列表
     */
    public setCSdkPaths(cSdkPaths: string[]): void {
        if (!this.config) {
            this.config = { ...this.defaultConfig };
        }
        this.config.cSdkPaths = cSdkPaths;
    }

    /**
     * 设置输出目录
     * @param outputDir 输出目录
     */
    public setOutputDir(outputDir: string): void {
        if (!this.config) {
            this.config = { ...this.defaultConfig };
        }
        this.config.outputDir = outputDir;
    }

    /**
     * 设置源文件路径列表
     * @param sourceFiles 源文件路径列表
     */
    public setSourceFiles(sourceFiles: string[]): void {
        if (!this.config) {
            this.config = { ...this.defaultConfig };
        }
        this.config.sourceFiles = sourceFiles;
    }

    /**
     * 获取完整配置
     */
    public getConfig(): DepGraphConfig {
        if (!this.config) {
            return { ...this.defaultConfig };
        }
        return { ...this.config };
    }

    /**
     * 获取项目路径
     */
    public getProjectPath(): string {
        return this.config?.projectPath || this.defaultConfig.projectPath;
    }

    /**
     * 获取SDK配置
     */
    public getSdk(): SDKConfig {
        return this.config?.sdk || this.defaultConfig.sdk;
    }

    /**
     * 获取ETS SDK路径
     */
    public getEtsSdkPath(): string {
        return this.getSdk().path;
    }

    /**
     * 获取C/C++ SDK路径列表
     */
    public getCSdkPaths(): string[] {
        return this.config?.cSdkPaths || this.defaultConfig.cSdkPaths;
    }

    /**
     * 获取输出目录
     */
    public getOutputDir(): string {
        return this.config?.outputDir || this.defaultConfig.outputDir;
    }

    /**
     * 获取源文件路径列表
     */
    public getSourceFiles(): string[] {
        return this.config?.sourceFiles || this.defaultConfig.sourceFiles;
    }

    /**
     * 获取输出文件的完整路径
     * @param fileName 文件名
     */
    public getOutputFilePath(fileName: string): string {
        const outputDir = this.getOutputDir();
        if (!fs.existsSync(outputDir)) {
            fs.mkdirSync(outputDir, { recursive: true });
        }
        return path.join(outputDir, fileName);
    }
}